package network.rpc.client;



import network.rpc.protocol.RpcRequest;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

public class RpcClient {
    private Socket socket;

    /**
     * 获取远程服务对象
     * @param serviceInterface 服务接口
     * @param serviceAddr   服务中心地址
     * @return  服务代理对象
     */
    public Object getRemoteServiceProxy(
            final Class<?> serviceInterface,
            final InetSocketAddress serviceAddr
    ) {
        // 使用jdk动态代理
        return Proxy.newProxyInstance(
                serviceInterface.getClassLoader(),
                new Class<?>[]{serviceInterface},
                (proxy, method, args) -> {  // 代理对象要干啥
                    System.out.println("> Proxy do work");
                    // 创建socket，与服务器建立连接
                    socket = new Socket();
                    socket.connect(serviceAddr);

                    System.out.println("> Socket connected");

                    // 将服务请求序列化成字节流传输
                    try (ObjectOutputStream outs = new ObjectOutputStream(socket.getOutputStream());
                         ObjectInputStream ins = new ObjectInputStream(socket.getInputStream())) {

                        outs.writeObject(new RpcRequest(
                                serviceInterface.getName(),
                                method.getName(),
                                method.getParameterTypes(),
                                args
                        ));

                        System.out.println("> Proxy sent RPC request");

                        // 阻塞等待服务请返回服务结果
                        return ins.readObject();
                    } finally {
                        if (socket != null) {
                            socket.close();
                        }
                    }
                }
        );
    }
}
